import { defineStore } from 'pinia'
import { computed, ref } from 'vue'

// Token 数据接口
export interface TokenInfo {
  accessToken: string
  refreshToken?: string
  tokenType?: string
  expiresIn?: number
  expiresAt?: number
}

// 用户基本信息接口
export interface UserInfo {
  id: string | number
  username: string
  nickname?: string
  avatar?: string
  email?: string
  phone?: string
  [key: string]: any
}

export const useTokenStore = defineStore(
  'token',
  () => {
    // 状态定义
    const tokenInfo = ref<TokenInfo | null>(null)
    const userInfo = ref<UserInfo | null>(null)

    // 计算属性：是否过期
    const isTokenExpired = computed(() => {
      if (!tokenInfo.value?.expiresAt) {
        return false
      }
      return Date.now() >= tokenInfo.value.expiresAt
    })

    // 计算属性：是否已登录
    const hasLogin = computed(() => {
      return !!(tokenInfo.value?.accessToken && !isTokenExpired.value)
    })

    // 计算属性：访问令牌
    const accessToken = computed(() => {
      return tokenInfo.value?.accessToken || ''
    })

    // 计算属性：剩余有效时间（秒）
    const remainingTime = computed(() => {
      if (!tokenInfo.value?.expiresAt) {
        return 0
      }
      const remaining = Math.floor((tokenInfo.value.expiresAt - Date.now()) / 1000)
      return Math.max(0, remaining)
    })

    // 方法：设置 Token 信息
    function setToken(token: TokenInfo) {
      // 如果有过期时间，计算绝对过期时间
      if (token.expiresIn && !token.expiresAt) {
        token.expiresAt = Date.now() + token.expiresIn * 1000
      }

      tokenInfo.value = { ...token }
      console.log('Token 已设置:', { ...token, accessToken: '***' })
    }

    // 方法：设置用户信息
    function setUserInfo(user: UserInfo) {
      userInfo.value = { ...user }
      console.log('用户信息已设置:', user)
    }

    // 方法：登录
    function login(token: TokenInfo, user?: UserInfo) {
      setToken(token)
      if (user) {
        setUserInfo(user)
      }
      console.log('用户登录成功')
    }

    // 方法：登出
    function logout() {
      tokenInfo.value = null
      userInfo.value = null
      console.log('用户已登出')
    }

    // 方法：刷新 Token
    function refreshToken(newToken: TokenInfo) {
      if (tokenInfo.value) {
        setToken(newToken)
        console.log('Token 已刷新')
      }
    }

    // 方法：清除过期 Token
    function clearExpiredToken() {
      if (isTokenExpired.value) {
        console.log('Token 已过期，自动清除')
        logout()
        return true
      }
      return false
    }

    // 方法：获取授权头
    function getAuthHeader() {
      if (!hasLogin.value) {
        return {}
      }

      const tokenType = tokenInfo.value?.tokenType || 'Bearer'
      return {
        Authorization: `${tokenType} ${accessToken.value}`,
      }
    }

    // 方法：检查并自动刷新 Token
    async function checkAndRefreshToken() {
      // 如果没有 refreshToken 或已经过期，直接退出登录
      if (!tokenInfo.value?.refreshToken || isTokenExpired.value) {
        logout()
        return false
      }

      // 如果距离过期时间小于 5 分钟，尝试刷新
      if (remainingTime.value < 300) {
        try {
          // 这里应该调用刷新 Token 的 API
          // const newToken = await refreshTokenApi(tokenInfo.value.refreshToken)
          // refreshToken(newToken)
          console.log('Token 即将过期，需要刷新')
          return true
        }
        catch (error) {
          console.error('刷新 Token 失败:', error)
          logout()
          return false
        }
      }

      return true
    }

    // 初始化时检查 Token 状态
    function init() {
      clearExpiredToken()
    }

    return {
      // 状态
      tokenInfo,
      userInfo,

      // 计算属性
      hasLogin,
      accessToken,
      isTokenExpired,
      remainingTime,

      // 方法
      setToken,
      setUserInfo,
      login,
      logout,
      refreshToken,
      clearExpiredToken,
      getAuthHeader,
      checkAndRefreshToken,
      init,
    }
  },
  {
    // 持久化配置
    persist: {
      key: 'token-store',
      storage: {
        getItem: (key: string) => {
          try {
            return uni.getStorageSync(key)
          }
          catch (error) {
            console.error(`获取存储数据失败: ${key}`, error)
            return null
          }
        },
        setItem: (key: string, value: string) => {
          try {
            uni.setStorageSync(key, value)
          }
          catch (error) {
            console.error(`保存存储数据失败: ${key}`, error)
          }
        },
      },
      // 只持久化必要的数据
      paths: ['tokenInfo', 'userInfo'],
    },
  },
)
